package com.wgo.precise.server.export;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import remato.common.domain.property.PropertyTypeEnumImpl;
import remato.domain.common.Category;
import remato.domain.common.Project;
import remato.domain.common.PropertyDef;
import remato.domain.common.PropertySet;
import remato.domain.common.PropertyValue;
import remato.domain.common.Requirement;
import remato.domain.common.RequirementSystem;
import remato.domain.common.Stakeholder;
import remato.domain.common.impl.CategoryImpl;
import remato.domain.common.impl.ProjectImpl;
import remato.domain.common.impl.PropertyDefImpl;
import remato.domain.common.impl.PropertySetImpl;
import remato.domain.common.impl.PropertyValueImpl;
import remato.domain.common.impl.RequirementImpl;
import remato.domain.common.impl.RequirementSystemImpl;
import remato.domain.common.impl.StakeholderImpl;

public class ExportImportFixture {
	private Random random = new Random();

	public RequirementSystem createRequirementSystem() {
		int reqCounter = 0;
		RequirementSystem reqSys = new RequirementSystemImpl();
		for (int s = 0; s < 10; s++) {
			Stakeholder stakeholder = new StakeholderImpl();
			stakeholder.setFirstName("Hayley_" + s);
			stakeholder.setLastName("Forskitt");
			stakeholder.setDescription("");
			reqSys.addStakeholder(stakeholder);
		}
		int noPropertySets = 10;
		for (int ps = 0; ps < noPropertySets; ps++) {
			PropertySet propertySet = new PropertySetImpl();
			propertySet.setName("propertySet name " + ps);
			propertySet.setDescription("propertySet description " + ps);
			for (int pd = 0; pd < 10; pd++) {
				PropertyDefImpl propertyDef = new PropertyDefImpl();
				int type = random.nextInt(3);
				if (0 == type) {
					propertyDef.setName("datePropDef " + pd);
					propertyDef.setPropertyTypeEnum(PropertyTypeEnumImpl.DATE);
					propertyDef.setDefaultValue("" + new Date(System.currentTimeMillis() + random.nextInt(10000)));
				} else if (1 == type) {
					propertyDef.setName("integerPropDef " + pd);
					propertyDef.setPropertyTypeEnum(PropertyTypeEnumImpl.INTEGER);
					propertyDef.setDefaultValue("" + random.nextInt(1000));
				} else if (2 == type) {
					propertyDef.setName("stringPropDef " + pd);
					propertyDef.setPropertyTypeEnum(PropertyTypeEnumImpl.STRING);
					propertyDef.setDefaultValue("DefaultString#" + random.nextInt(1000));
				}
				propertyDef.setDescription("");
				propertySet.addPropertyDef(propertyDef);
			}
			reqSys.addPropertySet(propertySet);
		}
		Project prevProj = null;
		for (int p = 0; p < 10; p++) {
			Project proj = new ProjectImpl();
			proj.setName("Project " + p);
			proj.setDescription("Project description #" + p);
			if ((null != prevProj) && random.nextBoolean()) {
				prevProj.addProjectChild(proj);
			} else {
				reqSys.addProjectChild(proj);
			}
			prevProj = proj;
			Category prevCat = null;
			for (int c = 0; c < 10; c++) {
				PropertySetImpl catPropertySet = null;
				Category cat = new CategoryImpl();
				cat.setName("Category " + c);
				if ((null != prevCat) && random.nextBoolean()) {
					cat.setDescription("Subcategory description #" + c);
					prevCat.addCategoryChild(cat);
				} else {
					cat.setDescription("Category description #" + c);
					proj.addCategoryChild(cat);
				}
				if (random.nextBoolean()) {
					catPropertySet = (PropertySetImpl)new ArrayList(reqSys.getPropertySets()).get(random.nextInt(reqSys.getPropertySets().size()));
					catPropertySet.setUpdatedDate(new Date(System.currentTimeMillis() - random.nextInt(10000000)));
					cat.addPropertySet(catPropertySet);
				}
				for (int r = 0; r < 10; r++) {
					RequirementImpl req = new RequirementImpl();
					assignPropertyValue(catPropertySet, req);
					req.setSubmittedDate(new Date(System.currentTimeMillis() - random.nextInt(1000000000)));
					req.setLastUpdatedDate(new Date(req.getSubmittedDate().getTime() + random.nextInt(10000000)));
					req.setBusinessId((long)reqCounter);
					req.setName("Requirement " + reqCounter);
					req.setDescription("Requirement description #" + reqCounter);
					int noStakeholders = random.nextInt(reqSys.getStakeholders().size());
					for (int s = 0; s < noStakeholders; s++) {
						Stakeholder stakeholder = reqSys.getStakeholders().iterator().next();
						req.addStakeholder(stakeholder);
					}
					Stakeholder assignedTo = (Stakeholder)new ArrayList(reqSys.getStakeholders()).get(random.nextInt(reqSys.getStakeholders().size()));
					req.setAssignedTo(assignedTo);
					Stakeholder reporterOrOwner = (Stakeholder)new ArrayList(reqSys.getStakeholders()).get(random.nextInt(reqSys.getStakeholders().size()));
					req.setReporterOrOwner(reporterOrOwner);
					req.setPriority(random.nextInt(5));
					req.setStatus(random.nextInt(8));
					req.setVersion("" + random.nextInt(100));
					if (0 < cat.getRequirements().size()) {
						Set<Requirement> linkedReqs = new HashSet<Requirement>();
						int noLinkedReqs = random.nextInt(5);
						for (int l = 0; l < noLinkedReqs; l++) {
							Requirement linkedReq = new ArrayList<Requirement>(cat.getRequirements()).get(random.nextInt(cat.getRequirements().size()));
							if (linkedReqs.add(linkedReq)) {
								req.addLinkedToRequirement(linkedReq);
							}
						}
					}
					cat.addRequirement(req);
					++reqCounter;
				}
				prevCat = cat;
			}
		}
		return reqSys;
	}

	private void assignPropertyValue(PropertySetImpl catPropertySet, RequirementImpl req) {
		PropertyValueImpl reqPropertyValue = null;
		if ((null != catPropertySet) && random.nextBoolean()) {
			PropertyDef propDef = (PropertyDef)catPropertySet.getPropertyDefs().get(random.nextInt(catPropertySet.getPropertyDefs().size()));
			reqPropertyValue = new PropertyValueImpl(propDef);
			reqPropertyValue.setValue(propDef.getDefaultValue());
			Set<PropertyValue> props = new HashSet<PropertyValue>();
			props.add(reqPropertyValue);
			req.setPropertyValues(props);
		}
	}

}
